import { CommandDialog, pickedVertexData } from '@amcax/base';
import i18n from '@app-cad/common/utils/i18next';
import { NMTopoBaseCommand } from '@app-cad/environments/nextmesh/types/command';
import { PickInputForFocus } from '@app-cad/common/components/command-form/auto-focus/pick-input';
import { CommandFormWrapper } from '@app-cad/common/components/command-form';
import { TopoDialogProps } from '../../topo/type';
import { useMemo, useState } from 'react';
import { CommandFormFooter } from '@app-cad/common/components/command-form/footer';
import { documentV2 } from '@app-nextmesh/domain';
import { Radio, RadioChangeEvent } from 'antd';

import { getCircleCenter, getXYZDistance } from '@app-nextmesh/utils';
import { MyMeasureResult } from './meaureResult';
import { Vector3 } from 'three-legacy';
import { useCommand } from '@app-base/common/hooks/useCommand';
import { PickInputValueType } from '@app-base/common/components/pick-input/types';

const measureType = {
  twoPoint: 'twoPts',
  threeCircleCenter: 'threeCircle',
};
function PointsMeasureDialog({ title, onClose }: TopoDialogProps) {
  const [firstPointData, setFirstPointData] = useState<pickedVertexData[]>([]);
  const [secondPointData, setSecondPointData] = useState<pickedVertexData[]>(
    [],
  );
  const [thirdPointData, setThirdPointData] = useState<pickedVertexData[]>([]);
  const [measureTab, setMeasureTab] = useState(measureType.twoPoint);
  const [distance, setDistance] = useState({
    x: 0,
    y: 0,
    z: 0,
  });
  const [centerPoint, setCenterPoint] = useState([0, 0, 0]);
  useCommand('cmdPointMeasure', {
    onClose,
  });
  useMemo(() => {
    if (
      measureTab === measureType.twoPoint &&
      firstPointData.length > 0 &&
      secondPointData.length > 0
    ) {
      const firstPoint = firstPointData[0].assisObj.positions;
      const secondPoint = secondPointData[0].assisObj.positions;
      const distanceObj = getXYZDistance(firstPoint, secondPoint);
      setDistance(distanceObj);
      // 两点之间的距离
    } else if (
      measureTab === measureType.threeCircleCenter &&
      firstPointData.length > 0 &&
      secondPointData.length > 0 &&
      thirdPointData.length > 0
    ) {
      const firstPoint = firstPointData[0].assisObj.positions;
      const secondPoint = secondPointData[0].assisObj.positions;
      const thirdPoint = thirdPointData[0].assisObj.positions;
      const firstPointVec = new Vector3(
        firstPoint[0],
        firstPoint[1],
        firstPoint[2],
      );
      const secondPointVec = new Vector3(
        secondPoint[0],
        secondPoint[1],
        secondPoint[2],
      );
      const thirdPointVec = new Vector3(
        thirdPoint[0],
        thirdPoint[1],
        thirdPoint[2],
      );
      const center = getCircleCenter(
        firstPointVec,
        secondPointVec,
        thirdPointVec,
      );
      setCenterPoint(center);
    }
  }, [firstPointData, secondPointData, thirdPointData, measureTab]);

  const onFirstPickData = (data) => {
    setFirstPointData(data);
  };
  const onSecondPickData = (data) => {
    setSecondPointData(data);
  };
  const onThirdPointData = (data) => {
    setThirdPointData(data);
  };
  const isValid = () => {
    if (measureTab === measureType.twoPoint) {
      return firstPointData.length > 0 && secondPointData.length > 0;
    } else {
      return (
        firstPointData.length > 0 &&
        secondPointData.length > 0 &&
        thirdPointData.length > 0
      );
    }
  };
  const handleSubmit = async () => {
    if (!isValid()) {
      return;
    }
    let measureIds: string[] = [];
    if (measureTab === measureType.twoPoint) {
      measureIds = [firstPointData[0].vertexId, secondPointData[0].vertexId];
    } else {
      measureIds = [
        firstPointData[0].vertexId,
        secondPointData[0].vertexId,
        thirdPointData[0].vertexId,
      ];
    }
    const params = {
      mode: measureTab,
      source: [...measureIds],
    };
    await documentV2.insertPoint(params, false);
    onClose();
  };
  const onTabChange = (e: RadioChangeEvent) => {
    if (e.target.value === measureType.twoPoint) {
      setMeasureTab(measureType.twoPoint);
      setThirdPointData([]);
      setCenterPoint([0, 0, 0]);
    } else {
      setMeasureTab(measureType.threeCircleCenter);
      setDistance({
        x: 0,
        y: 0,
        z: 0,
      });
    }
    setFirstPointData([]);
    setSecondPointData([]);
  };
  return (
    <CommandDialog
      title={title}
      placement='topLeft'
      className=''
      onClose={onClose}
    >
      <Radio.Group
        optionType='button'
        buttonStyle='solid'
        style={{
          width: '100%',
          textAlign: 'center',
        }}
        onChange={onTabChange}
        defaultValue={measureType.twoPoint}
      >
        <Radio.Button
          value={measureType.twoPoint}
          style={{ width: '40%' }}
        >
          两点之间
        </Radio.Button>
        <Radio.Button
          value={measureType.threeCircleCenter}
          style={{ width: '40%' }}
        >
          三点圆心
        </Radio.Button>
      </Radio.Group>
      <CommandFormWrapper>
        <PickInputForFocus
          autoFocus
          controlled
          allowPickType={[PickInputValueType.Vertex]}
          onPick={onFirstPickData}
          value={firstPointData}
          placeholder='请选择第一个点'
        ></PickInputForFocus>
        <PickInputForFocus
          allowPickType={[PickInputValueType.Vertex]}
          controlled
          onPick={onSecondPickData}
          value={secondPointData}
          placeholder='请选择第二个点'
        ></PickInputForFocus>
        {measureTab === measureType.threeCircleCenter ? (
          <PickInputForFocus
            allowPickType={[PickInputValueType.Vertex]}
            controlled
            value={thirdPointData}
            onPick={onThirdPointData}
            placeholder='请选择第三个点'
          ></PickInputForFocus>
        ) : null}
        <MyMeasureResult
          distance={distance}
          centerPoint={centerPoint}
          measureTab={measureTab}
        />
        <CommandFormFooter
          onClose={onClose}
          onSubmit={handleSubmit}
          submitText='插入点'
          isSubmitDisabled={!isValid()}
        />
      </CommandFormWrapper>
    </CommandDialog>
  );
}
export const cmdPointMeasure: NMTopoBaseCommand = {
  id: 'cmdBetweenTowPointMeasure',
  icon: 'commands/curved/point',
  label: 'command.topo.measure',
  create: (label: string, onClose: () => void, props) => (
    <PointsMeasureDialog
      title={i18n.t(label)}
      onClose={onClose}
      props={props}
      placement='topLeft'
    />
  ),
};
